package org.chen.processor;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.chen.model.ImageInfo;
import org.chen.model.Section;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.xsoup.Xsoup;

import java.util.*;

@Slf4j
public class ESPNSoccerPageProcessor extends AbstractESPNPageProcessor {
    // 添加随机User-Agent列表
    private static final String[] USER_AGENTS = {
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36 Edg/91.0.864.71"
    };

    // 添加随机Accept-Language列表
    private static final String[] ACCEPT_LANGUAGES = {
            "en-US,en;q=0.9",
            "en-GB,en;q=0.9",
            "en-CA,en;q=0.9",
            "en-AU,en;q=0.9",
            "en;q=0.9"
    };

    // 获取随机User-Agent
    private String getRandomUserAgent() {
        return USER_AGENTS[new Random().nextInt(USER_AGENTS.length)];
    }

    // 获取随机Accept-Language
    private String getRandomAcceptLanguage() {
        return ACCEPT_LANGUAGES[new Random().nextInt(ACCEPT_LANGUAGES.length)];
    }

    // 初始化Site配置，使用随机请求头
    private final Site site = Site.me()
            .setDomain("espn.com")
            .setSleepTime(1000)
            .setTimeOut(10000)  // 增加超时时间
            .setRetryTimes(3)   // 设置重试次数
            .setCycleRetryTimes(3)
            .setUserAgent(getRandomUserAgent())
            .addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
            .addHeader("Accept-Language", getRandomAcceptLanguage())
            .addHeader("Accept-Encoding", "gzip, deflate, br")
            .addHeader("Connection", "keep-alive")
            .addHeader("Upgrade-Insecure-Requests", "1")
            .addHeader("Cache-Control", "max-age=0")
            // 添加随机IP代理（如果需要的话）
            // .setProxy(new HttpHost("proxy-server", 8080))
            .addHeader("Referer", "https://www.espn.com");


    @Override
    public void processPage(Page page) {
        System.out.println("Soccer processing: " + page.getUrl());
        try {
            // 提取所有相关链接
            Set<String> links = new HashSet<>();
            // 添加文章链接
            links.addAll(page.getHtml()
                    .links()
                    .regex(".*/story/.*")
                    .all());

            // 添加球队链接
            links.addAll(page.getHtml()
                    .links()
                    .regex(".*/soccer/report\\?gameId=.*")
                    .all());

            page.addTargetRequests(new ArrayList<>(links));

            // 提取文章基本信息
            String title = page.getHtml()
                    .xpath("//header[@class='article-header']/h1/text()")
                    .get();

            String author = getString();

            String timestamp = page.getHtml()
                    .$("span.timestamp", "text")
                    .get();

            // 获取文章主体
            List<String> allElements = page.getHtml()
                    .$("div.article-body > *")  // 获取article-body下的所有直接子元素
                    .all();

            List<String> leadParagraphs = new ArrayList<>();
            List<Section> sections = new ArrayList<>();
            Section currentSection = null;

            // 处理文章内容
            for (String element : allElements) {
                // 检查元素是否是h2标题
                if (element.contains("<h2")) {
                    // 如果找到新的标题，创建新的Section
                    if (currentSection != null) {
                        sections.add(currentSection);
                    }
                    currentSection = new Section();
                    currentSection.setParagraphs(new ArrayList<>());

                    // 提取h2标签中的所有内容
                    Html h2Html = Html.create(element);

                    // 获取完整的标题文本（包括数字和球队名）
                    String fullHeading = h2Html.$("h2", "text").get();
                    currentSection.setHeading(fullHeading);

                    // 检查是否有链接
                    String teamUrl = h2Html.$("h2 a", "href").get();
                    if (teamUrl != null) {
                        // 提取链接中的球队名
                        String teamName = h2Html.$("h2 a", "text").get();
                        currentSection.setHeadingTeam(teamName);

                        log.info("Found team link: " + teamName + " -> " + teamUrl);
                    }
                }
                // 检查元素是否是段落
                else if (element.contains("<p")) {
                    String paragraphText = Xsoup.select(element, "//p/text()").get();
                    if (currentSection == null) {
                        // 如果还没有遇到标题，这是导语部分
                        leadParagraphs.add(paragraphText);
                    } else {
                        // 将段落添加到当前Section
                        currentSection.getParagraphs().add(paragraphText);
                    }
                }
            }

            // 添加最后一个section
            if (currentSection != null) {
                sections.add(currentSection);
            }

            // 提取图片信息
            List<ImageInfo> images = new ArrayList<>();
            // 获取所有figure元素
            List<String> figureElements = page.getHtml()
                    .$("aside.inline.inline-photo figure")
                    .all();

            // 遍历每个figure元素
            for (String figureElement : figureElements) {
                Html figureHtml = Html.create(figureElement);
                ImageInfo imageInfo = new ImageInfo();

                // 提取图片URL
                List<String> sources = figureHtml.$("picture source", "data-srcset").all();
                if (sources.isEmpty()) {
                    sources = figureHtml.$("picture source", "srcset").all();
                }

                if (!sources.isEmpty()) {
                    String srcset = sources.get(0);
                    String[] srcsetParts = srcset.split(",");

                    for (String part : srcsetParts) {
                        part = part.trim();
                        if (part.contains("w=570")) {
                            imageInfo.setMediumUrl(extractUrl(part));
                        } else if (part.contains("w=1140")) {
                            imageInfo.setLargeUrl(extractUrl(part));
                        }
                    }

                    // 处理第二个source（缩略图）
                    if (sources.size() > 1) {
                        String smallSrcset = sources.get(1);
                        String[] smallSrcsetParts = smallSrcset.split(",");
                        for (String part : smallSrcsetParts) {
                            part = part.trim();
                            if (part.contains("w=375")) {
                                imageInfo.setThumbnailUrl(extractUrl(part));
                            }
                        }
                    }
                }
                // 提取该figure下的图片说明和来源
                String caption = figureHtml.$("figcaption.photoCaption", "text").get();
                imageInfo.setCaption(caption != null ? caption.replaceAll("\\s+", " ").trim() : null);

                String credit = figureHtml.$("figcaption.photoCaption cite", "text").get();
                imageInfo.setCredit(credit != null ? credit.trim() : null);

                // 只有当图片信息完整时才添加到列表中
                if (isValidImageInfo(imageInfo)) {
                    images.add(imageInfo);
                    log.debug("Found image: thumbnail={}, medium={}, large={}",
                            imageInfo.getThumbnailUrl(),
                            imageInfo.getMediumUrl(),
                            imageInfo.getLargeUrl());
                }
            }

            // 仅当找到有效的图片信息时才保存
            if (!images.isEmpty()) {
                log.info("Found {} images for article", images.size());
                page.putField("images", images);
            }

            // 保存处理后的数据
            page.putField("title", title);
            page.putField("author", author);
            page.putField("timestamp", timestamp);
            page.putField("leadParagraphs", leadParagraphs);
            page.putField("sections", sections);
            page.putField("url", page.getUrl().toString());
            // 保存图片信息到Page对象
            page.putField("images", images);

            // 打印处理结果
            log.info("Found title: " + title);
            log.info("Found author: " + author);
            log.info("Lead paragraphs count: " + leadParagraphs.size());
            log.info("Sections count: " + sections.size());
            log.info("Sections count: " + images.size());

        } catch (Exception e) {
            log.error("Error processing page: " + page.getUrl(), e);
        }
    }

    // 验证图片信息的有效性
    private boolean isValidImageInfo(ImageInfo imageInfo) {
        return imageInfo != null
                && (imageInfo.getThumbnailUrl() != null
                || imageInfo.getMediumUrl() != null
                || imageInfo.getLargeUrl() != null)
                && !isDuplicateImage(imageInfo);  // 检查是否是重复图片
    }

    // 用于检测重复图片的集合
    private static final Set<String> processedImageUrls = Collections.synchronizedSet(new HashSet<>());

    // 检查是否是重复图片
    private boolean isDuplicateImage(ImageInfo imageInfo) {
        String imageUrl = imageInfo.getMediumUrl() != null ?
                imageInfo.getMediumUrl() :
                (imageInfo.getLargeUrl() != null ? imageInfo.getLargeUrl() : imageInfo.getThumbnailUrl());

        if (imageUrl != null) {
            if (processedImageUrls.contains(imageUrl)) {
                return true;
            }
            processedImageUrls.add(imageUrl);
            return false;
        }
        return true;
    }

    // 辅助方法：从srcset中提取URL
    private String extractUrl(String srcset) {
        // 移除宽度和2x等后缀
        String[] parts = srcset.split("\\s+");
        return parts[0].trim();
    }

    @Override
    public Site getSite() {
        return site;
    }

    private String replaceContent(String content) {
        if (StringUtils.isEmpty(content)) {
            return content;
        }

        // 创建更全面的替换规则
        return content
                // 基本替换
                .replaceAll("(?i)espn", "Bird Chat")
                .replaceAll("(?i)ESPN", "Bird Chat")
                .replaceAll("ESPN", "Bird Chat")
                .replaceAll("espn", "Bird Chat")
                .replaceAll("(?i)espn\\.com", "birdchat.com")

                // 作者和来源相关
                .replaceAll("(?i)espn staff", "Bird Chat Staff")
                .replaceAll("(?i)espn news services", "Bird Chat News")
                .replaceAll("(?i)espn contributor", "Bird Chat Contributor")
                .replaceAll("(?i)sources have told espn", "sources have told Bird Chat")
                .replaceAll("(?i)sources told espn", "sources told Bird Chat")
                .replaceAll("(?i)according to espn", "according to Bird Chat")
                .replaceAll("(?i)espn understands", "Bird Chat understands")
                .replaceAll("(?i)espn sources", "Bird Chat sources")
                .replaceAll("(?i)sources at espn", "sources at Bird Chat")

                // 专栏和节目相关
                .replaceAll("(?i)espn's", "Bird Chat's")
                .replaceAll("(?i)on espn", "on Bird Chat")
                .replaceAll("(?i)told espn", "told Bird Chat")
                .replaceAll("(?i)speaking to espn", "speaking to Bird Chat")
                .replaceAll("(?i)confirmed to espn", "confirmed to Bird Chat")

                // 确保替换句子开头的情况
                .replaceAll("(?i)^ESPN", "Bird Chat")

                // 处理特殊格式
                .replaceAll("(?i)\\[ESPN\\]", "[Bird Chat]")
                .replaceAll("(?i)\\(ESPN\\)", "(Bird Chat)")

                // 处理带标点符号的情况
                .replaceAll("(?i)espn,", "Bird Chat,")
                .replaceAll("(?i)espn\\.", "Bird Chat.")
                .replaceAll("(?i)espn\\?", "Bird Chat?")
                .replaceAll("(?i)espn!", "Bird Chat!")
                .replaceAll("(?i)espn;", "Bird Chat;")
                .replaceAll("(?i)espn:", "Bird Chat:");
    }

    private static String getString() {
        String[] authors = {
                "Bird Chat Editorial",
                "Admin Team",
                "Bird Chat Staff",
                "Admin Sports",
                "Bird Chat Sports",
                "Blink Sports",
                "Blink Chat Sports",
                "Blink Chat CN",
                "Bird Chat CN"
        };
        String author;
//            String author = page.getHtml()
//                    .$("div.author", "text")
//                    .get();
        Random random = new Random();
        author = authors[random.nextInt(authors.length)];
        return author;
    }
}
